#a framework of XMPP
#
import xmpp
import traceback

class Config:
    def __init__(self, configfile='gtalkbot2.conf'):
        self.owner = 'jimingxin@gmail.com'
        self.ownerPasswd = '790214'
        self.server = 'gmail.com'

class Bot:
    def __init__(self, connection):
        self.conn = connection

    def sendtoself(self, who, message):
        pass

    def sendtoother(self, who, message):
        pass

    def sendtoall(self, who, message):
        pass

    def sendtoone(self, who, message):
        pass


class Member:
    def __init__(self, connection, serverName, jid, isAdmin = False, status='', nickname = '', rp = 0):
        self.jid = jid
        self.isAdmin = isAdmin
        self.status = status
        self.nickname  = nickname
        self.rp = rp
        self.serverName = serverName
        self.conn = connection

    def getJID(self):
        x = self.getUser()
        if '@' not in x:
            x = x + "@" + self.serverName
        return x.lower()
        

    def getUser(self):
        x=unicode(self.jid)
        if '/' in x:
            x = x[:x.find("/")]
        if '@' in x and x[x.find('@'):] == "@" + self.serverName:
            x = x[:x.find("@")]
        return x.lower()

    def simpleInfo(self):
        #Used by names command
        result = self.getUser()
        if self.isAdmin:
            result = "@" + result

        return result

    def detailInfo(self):
        #Used by info command
        pass



class MemberManager:
    def __init__(self):
        self._dict = {}

    def Add(self, member):
        self._dict[member.getUser()] = member

    def getSimpleInfo(self):
        result = ''
        for key in self._dict.keys():
            result += self._dict[key].simpleInfo() + ', '
        return result

class BotServer:
    def __init__(self, config):
        self.config = config
        self.conn = xmpp.Client(self.config.server, debug=[])

        self.bot = Bot(self.conn)
        self.owner = Member(self.conn, self.config.server, self.config.owner, True)
        self.memberManager = MemberManager()
        self.memberManager.Add(self.owner)

    def start(self):
        connres = self.conn.connect(server=('talk.google.com', 5223))
        user = self.owner.getUser()
        passwd = self.config.ownerPasswd

        authres = self.conn.auth(user, passwd, "gtalkbot2")
        self.conn.sendInitPresence()
        self.conn.RegisterHandler('message', self.messageCB)
        self.conn.RegisterHandler('presence', self.presenceCB)

    def loop(self):
        try:
            while True:
                self.conn.Process(1)
        except KeyboardInterrupt:
            print "Bot Exited"
            return 

    def messageCB(self, conn, mess):
        text = mess.getBody()
        user = mess.getFrom()
        try:
#            r = self.conn.getRoster()
#            for i in r.getItems():
#                state = r.getStatus(unicode(i))
#                print i, ":", r.getName(i), ':', state

            self.conn.send(xmpp.Message(mess.getFrom(), "you typed:" + text))
        except:
            traceback.print_exc()

    def presenceCB(self, conn, prs):
        who = unicode(prs.getFrom())
        member = Member(self.conn, self.config.server, who)
        self.memberManager.Add(member)
        type = prs.getType()

        if type == 'subscribe':
            pass
        elif type == 'unsubscribe':
            pass
        elif type == 'subscribed':
            pass
        elif type == 'avaliable' or type == None:
            pass
        elif type == 'unavaliable':
            pass
        else:
            #Unknown presence
            pass

#        # TODO: Try only acking their subscription when they ack ours.
#        if type == 'subscribe':
#            print ">>> Subscribe from",whoid,
#            if isbanned(prs.getFrom().getStripped()):
#                print "Banned"
#                systoone(who, _('You are banned'))
#                boot(prs.getFrom().getStripped())
#            elif conf.general['private'] and not isuser(prs.getFrom().getStripped()):
#                print "Uninvited"
#                systoone(who, _('This is a private conference bot'))
#                boot(prs.getFrom().getStripped())
#            else:
#                print "Accepted"
#                con.send(jabber.Presence(to=who, type='subscribed'))
#                con.send(jabber.Presence(to=who, type='subscribe'))
#                systoall(_('<%s> joins this room.').para(getdisplayname(who)), [who])
#                userjid[whoid] = who
#        elif type == 'unsubscribe':
#            if userjid.has_key(whoid):
#                del userjid[whoid]
#            boot(prs.getFrom().getStripped())
#            print ">>> Unsubscribe from",who
#        elif type == 'subscribed':
#            if i18n.isobj(welcome):
#                wel = welcome.getvalue()
#            else:
#                wel = welcome
#            systoone(who, wel % {'version':version})
#            systoone(who, _('''Topic: %(topic)s
#    %(lastlog)s''').para({
#                "topic" : conf.general['topic'],
#                "lastlog" : "\n".join(lastlog),
#                })  + '\n---------------------------')
#            sendstatus(who, _('here'), _('joining'))
#            userjid[whoid] = who
#        elif type == 'unsubscribed':
#            if userjid.has_key(whoid):
#                del userjid[whoid]
#            boot(prs.getFrom().getStripped())
#            systoall(_('<%s> has left').para(getdisplayname(who)))
#        elif type == 'available' or type == None:
#            show = prs.getShow()
#            if show in [None,'chat','available','online']:
#                sendstatus(who, _('here'),prs.getStatus())
#            elif show in ['xa']:
#                sendstatus(who, _('away'),prs.getStatus())
#            elif show in ['away']:
#                sendstatus(who, _('away'),prs.getStatus())
#            elif show in ['dnd']:
#                sendstatus(who, _('away'),prs.getStatus())
#            else:
#                sendstatus(who, _('away'),show+" [[%s]]" % prs.getStatus())
#            userjid[whoid] = who
#        elif type == 'unavailable':
#            status = prs.getShow()
#            sendstatus(who, _('away'),status)
#        else:
#            if conf.general.debug > 3:
#                print ">>> Unknown presence:",who,type

if __name__ == '__main__':
    server = BotServer(Config('gtalkbot2.conf'))
    server.start()
    server.loop()
